package com.yqm.pathlearning;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class DragBubbleView extends View {

    private static final float MAX_DISTANCE = 300f;
    private static final float RADIUS = 50f;

    private float mTouchX;
    private float mTouchY;
    private float mMoveX;
    private float mMoveY;
    private float mLeaveX;
    private float mLeaveY;
    // 控制点横坐标
    private float mControlX;
    // 控制点纵坐标
    private float mControlY;
    private float sin;
    private float cos;
    private float mCurrentDistance;
    private float mCurrentRadius;
    private float mCircleCenterX = 300f;
    private float mCircleCenterY = 300f;
    private boolean mFlagTouched;
    private Context mContext;
    private Paint mPaint;
    private Path mPath;

    public DragBubbleView(Context context) {
        super(context, null);
    }

    public DragBubbleView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(1);
        mPath = new Path();
        mPath.setFillType(Path.FillType.WINDING);
        mPath.addCircle(mCircleCenterX, mCircleCenterY, RADIUS, Path.Direction.CW);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawPath(mPath, mPaint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mTouchX = event.getX();
                mTouchY = event.getY();
//                if (mTouchX == mCircleCenterX && mTouchY == mCircleCenterY) {
                    mFlagTouched = true;
//                }
                break;
            case MotionEvent.ACTION_MOVE:
                mMoveX = event.getX();
                mMoveY = event.getY();

                mCurrentRadius = RADIUS * (1 - (mCurrentDistance / MAX_DISTANCE));
                mCurrentDistance = (float) Math.hypot(mMoveX - mCircleCenterX, mMoveY - mCircleCenterY);

                if (mFlagTouched && (mCurrentRadius < RADIUS) && (mCurrentRadius > 10)) {
                    doDragBubble();
                } else if (mFlagTouched && (mCurrentRadius <= 10)) {
                    doMoveBubble();
                }
                break;
            case MotionEvent.ACTION_UP:
                mLeaveX = event.getX();
                mLeaveY = event.getY();
                mCurrentDistance = (float) Math.hypot(mLeaveX - mCircleCenterX, mLeaveY - mCircleCenterY);
                if (mFlagTouched && (mCurrentDistance >= MAX_DISTANCE)) {
                    doDisappearBubble();
                } else if (mFlagTouched && (mCurrentDistance < MAX_DISTANCE)){
                    doRestoreBubble();
                }
                break;
        }
        invalidate();
        return true;
    }

    private void doMoveBubble() {
        mPath.reset();
        mPath.addCircle(mMoveX, mMoveY, RADIUS, Path.Direction.CW);
    }

    private void doRestoreBubble() {
        mPath.reset();
        mPath.addCircle(mCircleCenterX, mCircleCenterY, RADIUS, Path.Direction.CW);
    }

    private void doDisappearBubble() {
        mPath.reset();
        mPath.addCircle(mCircleCenterX, mCircleCenterY, RADIUS, Path.Direction.CW);
    }

    private void doDragBubble() {
        sin = (mMoveX - mCircleCenterX) / mCurrentDistance;
        cos = (mMoveY - mCircleCenterY) / mCurrentDistance;
        mControlX = (mCircleCenterX + mMoveX) / 2;
        mControlY = (mCircleCenterY + mMoveY) / 2;

        mPath.reset();
        // 绘制按比例缩放后的小圆
        mPath.addCircle(mCircleCenterX, mCircleCenterY, mCurrentRadius, Path.Direction.CW);
        // 绘制移动位置的小圆
        mPath.addCircle(mMoveX, mMoveY, RADIUS, Path.Direction.CW);
        mPath.moveTo(mCircleCenterX - mCurrentRadius * sin, mCircleCenterY + mCurrentRadius * cos);
        mPath.quadTo(mControlX, mControlY
                , mMoveX - RADIUS * sin
                , mMoveY + RADIUS * cos);
//        mPath.lineTo(mMoveX + RADIUS * sin, mMoveY - RADIUS * cos);
        mPath.moveTo(mMoveX + RADIUS * sin, mMoveY - RADIUS * cos);
        mPath.quadTo(mControlX, mControlY
                , mCircleCenterX + mCurrentRadius * sin
                , mCircleCenterX - mCurrentRadius * cos);
//        mPath.close();
    }
}
